package com.himiotech.core.project.web.base.model;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.himiotech.core.framework.helper.exception.HimioException;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 网络传输对象
 * created by Wuwenbin on 2017/12/20 at 下午3:39
 *
 * @author wuwenbin
 */
public class HimioResult extends HashMap<String, Object> {

    public static final String CODE = "code";
    public static final String MESSAGE = "message";
    public static final String MSG = "msg";
    public static final String DATA = "data";
    public static final int SUCCESS_CODE = 0;
    public static final int ERROR_CODE = -1;
    public static final String SUCCESS_MESSAGE = "操作成功！";
    public static final String ERROR_MESSAGE = "操作失败！";
    private static final long serialVersionUID = 1L;

    private HimioResult() {
    }

    public static HimioResult create(int code, String msg, Object data) {
        HimioResult himioResult = new HimioResult();
        himioResult.put(CODE, code);
        himioResult.put(MESSAGE, msg);
        himioResult.put(MSG, msg);
        if (data != null) {
            himioResult.put(DATA, data);
        }
        return himioResult;
    }


    public static HimioResult ok() {
        return create(SUCCESS_CODE, SUCCESS_MESSAGE, null);
    }

    public static HimioResult okMsg(String message) {
        return create(SUCCESS_CODE, message, null);
    }

    public static HimioResult okMsgFormat(String message, Object... args) {
        return okMsg(StrUtil.format(message, args));
    }

    public static HimioResult okData(Object data) {
        return create(SUCCESS_CODE, SUCCESS_MESSAGE, data);
    }

    public static HimioResult okMsgData(String message, Object data) {
        return create(SUCCESS_CODE, message, data);
    }


    public static HimioResult err() {
        return create(ERROR_CODE, ERROR_MESSAGE, null);
    }

    public static HimioResult errMsg(String message) {
        return create(ERROR_CODE, message, null);
    }

    public static HimioResult errMsgFormat(String message, Object... msgParam) {
        return create(ERROR_CODE, StrUtil.format(message, msgParam), null);
    }


    public static HimioResult errMsgData(String message, Object data) {
        return create(ERROR_CODE, message, data);
    }

    public static HimioResult errData(Object data) {
        return create(ERROR_CODE, ERROR_MESSAGE, data);
    }

    public static HimioResult errException(HimioException e) {
        return create(ERROR_CODE, StrUtil.isNotEmpty(e.getMessage()) ? e.getMessage() : ERROR_MESSAGE, null);
    }


    /**
     * 添加额外的返回对象
     *
     * @param extraMap
     * @return
     */
    public HimioResult addExtra(Map<String, Object> extraMap) {
        this.putAll(extraMap);
        return this;
    }

    public HimioResult addExtra(String extraKey, Object extraObj) {
        this.put(extraKey, extraObj);
        return this;
    }

    public boolean isSuccess() {
        return MapUtil.getInt(this, CODE) == SUCCESS_CODE;
    }

    public Integer getIntData() {
        return MapUtil.getInt(this, DATA);
    }

    public String getStrData() {
        return MapUtil.getStr(this, DATA);
    }

    public Long getLongData() {
        return MapUtil.getLong(this, DATA);
    }

    public Double getDoubleData() {
        return MapUtil.getDouble(this, DATA);
    }

    public char getCharData() {
        return MapUtil.getChar(this, DATA);
    }

    public Boolean getBoolData() {
        return MapUtil.getBool(this, DATA);
    }

    public Float getFloatData() {
        return MapUtil.getFloat(this, DATA);
    }

    public Short getShortData() {
        return MapUtil.getShort(this, DATA);
    }

    public Object getData() {
        return this.get(DATA);
    }

    public <T> T getDataBean(Class<T> clazz) {
        return MapUtil.get(this, DATA, clazz);
    }

    public <T> List<T> getDataListBean() {
        //noinspection unchecked
        return MapUtil.get(this, DATA, List.class);
    }

    public Boolean getDataBool() {
        return Convert.toBool(getData());
    }

    public String getDataStr() {
        return Convert.toStr(getData());
    }

    public Integer getDataInt() {
        return Convert.toInt(getData());
    }

    public Long getDataLong() {
        return Convert.toLong(getData());
    }

    public Double getDataDouble() {
        return Convert.toDouble(getData());
    }

    public Float getDataFloat() {
        return Convert.toFloat(getData());
    }

    public Byte getDataByte() {
        return Convert.toByte(getData());
    }

    public char getDataChar() {
        return Convert.toChar(getData());
    }

    public BigDecimal getDataBigDecimal() {
        return Convert.toBigDecimal(getData());
    }

    public Date getDataDate() {
        return Convert.toDate(getData());
    }

    public Short getDataShort() {
        return Convert.toShort(getData());
    }

    public <K, V> Map<K, V> getDataMap(Class<K> keyClass, Class<V> valueClass) {
        return Convert.toMap(keyClass, valueClass, getData());
    }

    public String getMsg() {
        return MapUtil.getStr(this, MESSAGE);
    }

    public void setMsg(String message) {
        this.put(MESSAGE, message);
    }

    public Integer getCode() {
        return MapUtil.getInt(this, CODE);
    }

}
